package com.uziot.activiti6.service;

import com.uziot.activiti6.service.ProcessDefinitionService;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.repository.Deployment;
import org.apache.commons.io.FilenameUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.List;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.zip.ZipInputStream;

/**
 * @author shidt
 * @version V1.0
 * @className ProcessDefinitionService
 * @date 2021-02-26 10:38:41
 * @description 工作流服务接口
 */

@Service
public class ProcessDefinitionServiceImpl implements ProcessDefinitionService {
    @Autowired
    private RepositoryService repositoryService;
    @Autowired
    private HistoryService historyService;
    @Autowired
    private RuntimeService runtimeService;

    @Override
    public int deleteProcessDefinitionById(String id) {
        repositoryService.deleteDeployment(id, false);
        return 1;
    }

    @Override
    public int deleteAllProcessDefinition() {
        List<Deployment> deployments = repositoryService.createDeploymentQuery().list();
        AtomicInteger i = new AtomicInteger();
        deployments.forEach(processDefinition -> {
            repositoryService.deleteDeployment(processDefinition.getId(), false);
            i.getAndIncrement();
        });
        return i.get();
    }

    @Override
    public void uploadStreamAndDeployment(MultipartFile file) throws IOException {
        // 获取上传的文件名
        String fileName = file.getOriginalFilename();
        // 得到输入流（字节流）对象
        InputStream fileInputStream = file.getInputStream();
        // 文件的扩展名
        String extension = FilenameUtils.getExtension(fileName);

        if ("zip".equals(extension)) {
            ZipInputStream zip = new ZipInputStream(fileInputStream);
            // 初始化流程
            repositoryService.createDeployment()
                    .addZipInputStream(zip)
                    .deploy();
        } else {
            // 初始化流程
            repositoryService.createDeployment()
                    .addInputStream(fileName, fileInputStream)
                    .deploy();
        }
    }

    @Override
    public void suspendOrActiveApply(String id, Integer suspendState) {
        if (1 == suspendState) {
            // 当流程定义被挂起时，已经发起的该流程定义的流程实例不受影响
            // （如果选择级联挂起则流程实例也会被挂起）。
            // 当流程定义被挂起时，无法发起新的该流程定义的流程实例。
            // 直观变化：act_re_procdef 的 SUSPENSION_STATE_ 为 2
            repositoryService.suspendProcessDefinitionById(id);
        } else if (2 == suspendState) {
            repositoryService.activateProcessDefinitionById(id);
        }
    }

    @Override
    public String upload(MultipartFile multipartFile) {
        return null;
    }

    @Override
    public void addDeploymentByString(String stringBpmn) {
        repositoryService.createDeployment()
                .addString("CreateWithBPMNJS.bpmn", stringBpmn)
                .deploy();
    }

    @Override
    public void getProcessDefineXml(HttpServletResponse response, String deploymentId, String resourceName) throws IOException {
        InputStream inputStream = repositoryService.getResourceAsStream(deploymentId, resourceName);
        int count = inputStream.available();
        byte[] bytes = new byte[count];
        response.setContentType("text/xml");
        OutputStream outputStream = response.getOutputStream();
        while (inputStream.read(bytes) != -1) {
            outputStream.write(bytes);
        }
        inputStream.close();
    }
}
